package 
{
	import flash.events.MouseEvent;
	import flash.display.Sprite;
	import flash.utils.ByteArray;
	
	/**
	 * ...
	 * @author DarkGoodWIN
	 */
	public class TNaperstokRich extends TCaseRoom
	{				
		private var MainCont: TContainer = null;
		private var PrisesOnCaseColl: Array = new Array();
		
		private function CopyByteArray(Source: ByteArray): ByteArray
		{
			var Res: ByteArray = new ByteArray();
			for (var i: int = 0; i < Source.length; ++i)
				Res[i] = Source[i];
			return Res;
		}
		
		protected override function UpdateMoneyText(): void
		{
			MoneyText.Text = Info.UserNameText.Text;
		}
		
		private function AddPrisesToCase(Prises: ByteArray, PrisesOnCase: ByteArray): ByteArray
		{
			var Res: ByteArray = CopyByteArray(Prises);
			var N: int = 0;
			var ID: int = 0;
			while ((N <= PrisesOnCase.length) && (PrisesOnCase[N] != 0))
			{
				ID = PrisesOnCase[N];
				if ((ID > 0) && ((Res[ID - 1] > 0) || (!(Info.IsInHome()))))
				{
					--Res[ID - 1];
					var P: TPrise = CreatePrize(ID);
					P.X = Stored2RealPos(PrisesOnCase[N + 2]);
					PutPrise2CaseByInd(P, PrisesOnCase[N + 1]);
				}
				N += 3;
			}
			return Res;
		}
		
		private function AddPrizes(): void
		{
			var Prises: ByteArray = CopyByteArray(Info.Prises);
			Prises = AddPrisesToCase(Prises, Info.PrisesOnCase);
			if (!(Info.IsInHome()))
				return;
			for (var i: int = 0; i < Prises.length; ++i)
				for (var j: int = 0; j < Prises[i]; ++j)
					AddPrize(i + 1);
		}
		
		public override function CurrentCont(): TContainer
		{
			return MainCont;
		}
		
		private function FindCont(X: int, Y: int): TContainer
		{
			return CurrentCont();
		}
		
		private var CaseHeights: Array = [115, 122, 137, 123];			
		
		private function CaseIndexByYPos(Y: int): int
		{
			var Sum: int = Case.Y;
			for (var i: int = 0; i < CaseHeights.length ; ++i)
			{
				Sum += CaseHeights[i];
				if (Y < Sum)
					return i;
			}			
			return -1;
		}
		
		private function GetCaseTopByIndex(index: int): int
		{
			var Sum: int = Case.Y;
			for (var i: int = 0; i < index + 1; ++i)
			{
				Sum += CaseHeights[i];
			}			
			return Sum;
		}
		
		private function PutPrise2CaseByInd(P: TPrise, Index: int): Boolean
		{
			if (Index < 0)
				return false;
				
			
			if (P.X < Case.X)
				P.X = Case.X;
			if (P.X + P.Width > Case.X + Case.Width)
				P.X = Case.X + Case.Width - P.Width;
				
			P.X = CorrectPosForStore(P.X);
			P.Y = GetCaseTopByIndex(Index) - P.Height;
			
			return AddToPrisesOnCaseColl(P, Index);
		}
		
		private function AddToPrisesOnCaseColl(P: TPrise, Index: int): Boolean
		{
			if (PrisesOnCaseColl.length > 83)
			{
				new TModalMessage("Вы не можете больше <br> класть подарки в шкаф");
				return false;
			}
			var N: int = PrisesOnCaseColl.length;
				PrisesOnCaseColl[N] = new Object();
			PrisesOnCaseColl[N]['ID'] = P.ID;
			PrisesOnCaseColl[N]['X'] = P.X;
			PrisesOnCaseColl[N]['Y'] = P.Y;
			PrisesOnCaseColl[N]['CaseIndex'] = Index;
			return true;
		}
		
		private function RemoveFromPrisesOnCaseColl(P: TPrise): void
		{
			var O: Object = null;
			for (var I: int = 0; I < PrisesOnCaseColl.length; ++I)
			{
				O = PrisesOnCaseColl.shift();
				if (O == null)
					return;
				if (!((O.ID == P.ID) && (O.X == P.X) && (O.Y == P.Y)))
					PrisesOnCaseColl[PrisesOnCaseColl.length] = O
				else
					return;
			}
		}
		
		private function PutPrise2Case(P: TPrise, X: int, Y: int): Boolean
		{
			var Index: int = CaseIndexByYPos(Y);
			//return (AddPriseToCaseArray(P, X, Index)) && PutPrise2CaseByInd(P, X, Index))
			return PutPrise2CaseByInd(P, Index);
		}
		
			/*
		private function AddPriseToCaseArray(P: TPrise, X: int, CaseIndex: int): Boolean
		{
			var N: int = 0;
			while ((N <= Info.PrisesOnCase.length) && (Info.PrisesOnCase[N] != 0))
				N += 3;
			if (N > 252)
				return false;
			Info.PrisesOnCase[N] = P.ID;
			Info.PrisesOnCase[N + 1] = CaseIndex;
			Info.PrisesOnCase[N + 2] = Real2StoredPos(X);
			Info.UpdatePrisesOnCase2Server();
			return true;
		}
			*/
		private function UpdatePrisesOnCaseToServer(): void
		{
			StringUtils.String2ByteArr('', Info.PrisesOnCase, 255);
			for (var I: int = 0; I < PrisesOnCaseColl.length; ++I)
			{
				Info.PrisesOnCase[3 * I] = PrisesOnCaseColl[I].ID;
				Info.PrisesOnCase[3 * I + 1] = PrisesOnCaseColl[I].CaseIndex;
				Info.PrisesOnCase[3 * I + 2] = Real2StoredPos(PrisesOnCaseColl[I].X);				
			}
			
			Info.UpdatePrisesOnCase2Server();
		}
		
		private function StoredPosStep(): int
		{
			return Math.round(Case.Width / 143); //143 = StringUtils.MaxCharCode
		}
		
		private function CorrectPosForStore(Pos: int): int
		{
			return Pos2StoredPos(Pos) * StoredPosStep();
		}
		
		private function Stored2RealPos(StoredPos: int): int
		{
			return StoredPos * StoredPosStep();
		}
		
		private function Real2StoredPos(RealPos: int): int
		{
			return Math.round(RealPos / StoredPosStep());
		}
		
		private function Pos2StoredPos(Pos: int): int
		{
			return Math.round(Pos / StoredPosStep());			
		}
		
		private function CanPutPrise2Case(P: TPrise, X: int, Y: int): Boolean
		{
			var Res: Boolean = false;
			Res = (X > Case.X) && (X < Case.X + Case.Width) && (Y > Case.Y) && (Y < Case.Y + Case.Height);
			return Res;
		}
		
		private var DragControlIndex: int = -1;
		private var OldPosX: int = -1;
		private var OldPosY: int = -1;
		
		public override function OnPriseMDown(P: TPrise, X: int, Y: int): void
		{
			if (!(Info.IsInHome()))
				return;
			DragControlIndex = MainCont.PeekControl(P);
			OldPosX = P.X;
			OldPosY = P.Y;

			AddChild(P);
			RemoveFromPrisesOnCaseColl(P);
			(P.Ctrl as Sprite).startDrag();
		}
		
		private function TryPut2Case(P: TPrise, X: int, Y: int): void
		{
			if (!(CanPutPrise2Case(P, X, Y) && PutPrise2Case(P, X, Y)))
			{
				if (DragControlIndex >= 0)
					MainCont.AddControlAt(DragControlIndex, P)
				else
				{
					P.X = OldPosX;
					P.Y = OldPosY;
				}
			}			
		}
		
		private function TryBackToMainCont(P: TPrise, X: int, Y: int): Boolean
		{
			var Res: Boolean = false;
			if (P == null)
				return Res;
			Res = (X > MainCont.X) && (X < MainCont.X + MainCont.Width) && (Y > MainCont.Y) && (Y < MainCont.Y + MainCont.Height);
			if (Res)
			{
				MainCont.Lock();
				try
				{
					MainCont.AddControl(P);
				}				
				finally
				{
					MainCont.UnLock();
				}
				MainCont.sortOn('ID', Array.NUMERIC);
			}
			return Res;
		}
		
		private function DoPriseMUp(P: TPrise, X: int, Y: int): void
		{
			if ((P.X == OldPosX) && (P.Y == OldPosY))
				return;
			if (Info.VKNaperstokAPI.CurrentID != Info.VKNaperstokAPI.ViewerID)
				return;
			if (!(TryBackToMainCont(P, X, Y)))
				TryPut2Case(P, X, Y);
			UpdatePrisesOnCaseToServer();			
		}
		
		public override function OnPriseMUp(P: TPrise, X: int, Y: int): void
		{
			DoPriseMUp(P, X, Y);
			(P.Ctrl as Sprite).stopDrag();
			DragControlIndex = -1;
		}
		
		private function Prise2Friend(FriendID: int, PriseID: int): Boolean
		{
			return false;
		}
		
		private var CurPrise: TPrise = null; //todo: remove

		private function OnChooseFriend(O: Object): void
		{
			var N: int = O.Freind;
			if (N < 0)
				return;
			if (!(Prise2Friend(N, CurPrise.ID)))
				return;
			RemoveFromPrisesOnCaseColl(CurPrise);
			UpdatePrisesOnCaseToServer();
			Close();
			new TNaperstokRich(Info);			
		}
		
		private function ChooseFriend(): void
		{
			var Chooser: FriendsChooser = new FriendsChooser(Info, OnChooseFriend);
		}
		
		private function OnPrise2Friend(e: MouseEvent): void
		{
			ChooseFriend();
		}
		
		public override function OnPriseClick(P: TPrise): void
		{
			if (!(Info.IsInHome()))
				return;
			if (!((Math.abs(P.X - OldPosX) < 3) && (Math.abs(P.Y - OldPosY) < 3)))
				return;
			CurPrise = P;
			var Ask: TModalMessage = new TModalMessage('Хотите подарить <br> <b> ' + P.Hint + '</b>?', false);
			Ask.AddBtn('Можно', OnPrise2Friend, true);
			Ask.AddCloseBtn('       Нет уж!!');
		}
		
		private function LogPrice(): void
		{
			Info.Log.Log('Вам подарили');
			Info.Log.Log("<img src='../lib/prize_heart.png' width='40%' height='40%' align='center'>");
			Info.Log.Log(' ');
			Info.Log.Log(' ');
			Info.Log.Log(' ');
			Info.Log.Log(' ');			
		}
		
		public function TNaperstokRich(anInfo: TNaperstokInfo): void
		{
			super(anInfo);
			MainCont = new TContainer(this, 600, 90, 120, 500, true);
			MainCont.MaxElementHeight = 120 - 2 * MainCont.BorderWidth;
			MainCont.Visible = anInfo.IsInHome();
			AddPrizes();
		}	
	}
}